/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpb.projetoesa.dados;

import br.ufpb.projetoesa.exceptions.AtualizacaoDeProfessorException;
import br.ufpb.projetoesa.exceptions.ProfessorInexistenteException;
import br.ufpb.projetoesa.exceptions.ProfessorInvalidoException;
import br.ufpb.projetoesa.negocio.Professor;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JOptionPane;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

/**
 *
 * @author Filipe
 */
public class ProfessorDAOArquivoBin implements ProfessorDAO {

    private File arquivo;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    
    private static ProfessorDAOArquivoBin daoArquivoBin; 
    
    
     public static ProfessorDAOArquivoBin getInstance(){
        if (daoArquivoBin == null)
            return new ProfessorDAOArquivoBin();
        return daoArquivoBin;
    }
    
    public ProfessorDAOArquivoBin(){
        arquivo = new File("Professores.bin");
    }
    
    @Override
    public void salvar(Professor p) {
       try {
           if(!arquivo.exists()){
               out = new ObjectOutputStream(new FileOutputStream(arquivo));
               List<Professor> professores = new ArrayList<Professor>();
               professores.add(p);
               out.writeObject(professores);
               out.flush();
               out.close();
           } else {
               if (!existe(p)){
                 in = new ObjectInputStream(new FileInputStream(arquivo));
                List<Professor> professores = (ArrayList<Professor>) in.readObject();
                out = new ObjectOutputStream(new FileOutputStream(arquivo));
                professores.add(p);
                out.writeObject(professores);
                out.flush();
                out.close();
                in.close();
               } else {
                  throw new ProfessorInvalidoException("Este professor ja existe"); 
               }  
           }
       } catch (IOException exp1){
           exp1.printStackTrace();
       } catch (ClassNotFoundException exp2){
           exp2.printStackTrace();
       }
           
    }
    
    public boolean existe(Professor p){
       try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            in.close();
            for (Professor pro : lista){
                if (pro.getMatricula().equals(p.getMatricula())) {
                    return true;
                }
            }
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return false;
    }

    @Override
    public void remover(Professor p) {
        try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> professores = (ArrayList<Professor>) in.readObject();
            in.close();
            int tam = professores.size();
            if (professores!=null){
                 for (Professor pro : professores){
                      if (pro.getMatricula().equals(p.getMatricula())){
                          professores.remove(pro);
                          break;
                      }          
                 }
                 if(professores.size()==tam){
                     throw new ProfessorInexistenteException("Não foi possível remover o professor.");
                  } else {
                    out = new ObjectOutputStream(new FileOutputStream(arquivo));
                    out.writeObject(professores);
                    out.flush();
                    out.close();
                  }
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            }      
            
        } catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
        }
    }

   

    @Override
    public void removerPorMatricula(String matricula) {
         try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> professores = (ArrayList<Professor>) in.readObject();
            in.close();
            int tam = professores.size();
            if (professores!=null){
                 for (Professor p : professores){
                      if (p.getMatricula().equals(matricula)){
                          professores.remove(p);
                          break;
                      }          
                 }
                 if(professores.size()==tam){
                     throw new ProfessorInexistenteException("Não foi possível remover o professor.");
                  } else {
                    out = new ObjectOutputStream(new FileOutputStream(arquivo));
                    out.writeObject(professores);
                    out.flush();
                    out.close();
                  }
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            }      
            
        } catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
        }
    }

    @Override
    public void atualizar(Professor p) {
        try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>) in.readObject();
            int gambiarra = 0;
            for (Professor pro : lista){
                if (pro.getMatricula().equals(p.getMatricula())) {
                    gambiarra = 1;
                    lista.remove(pro);
                    lista.add(p);
                }
            }
            if (gambiarra==1){
                out = new ObjectOutputStream(new FileOutputStream(arquivo));
                out.writeObject(lista);
                in.close();
                out.flush();
                out.close();
            } else {
                throw new AtualizacaoDeProfessorException("Não foi possível encontrar o professor e atualizar seus dados, "
                        + "verifique e tente novamente.");
            }
	} catch (IOException exp1) {
            exp1.printStackTrace();
        } catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
	} catch (AtualizacaoDeProfessorException exp3){
            exp3.getMessage();
        }

	
    }

    @Override
    public Professor getProfessor(Professor p) {
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            if (lista != null){
                 for (Professor pro : lista){
                    if (pro.getMatricula().equals(p.getMatricula())) {
                        return pro;
                    }
                }
            throw new ProfessorInexistenteException("Não foi possível encontrar este professor");
            } else {
                throw new ProfessorInexistenteException("Não existe Professores cadastrados.");
            } 
           
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }

    

    @Override
    public Professor getProfessorMatricula(String matricula) {
       try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();
            for (Professor pro : lista){
                if (pro.getMatricula().equals(matricula)) {
                    return pro;
                }
            }
            throw new ProfessorInexistenteException("Não foi possível encontrar este professor");
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Professor> getProfessores() {
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject();  
            return lista;
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return null;
    }
    
    
    public int size(){
        List<Professor> lista = new ArrayList<Professor>();
	try {
            in = new ObjectInputStream(new FileInputStream(arquivo));
            lista = (ArrayList<Professor>) in.readObject();
            in.close();
            return lista.size();
	} catch (IOException exp1) {
            exp1.printStackTrace();
	} catch (ClassNotFoundException exp2) {
            exp2.printStackTrace();
	}
        
	return lista.size();
    }

    @Override
    public List<Professor> buscarTodosComProjeto() {
      List<Professor> retorno = new ArrayList<Professor>();
        try {	
            in = new ObjectInputStream(new FileInputStream(arquivo));
            List<Professor> lista = (ArrayList<Professor>)in.readObject(); 
            for(Professor pro : lista){
                if (!pro.getProjetos().isEmpty()){
                    retorno.add(pro);
                }
            }
        } catch (IOException exc1) {
            exc1.printStackTrace();
        } catch (ClassNotFoundException exc2) {
            exc2.printStackTrace();
        }
        return retorno;
    }
    
    
}
